#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
电影海报爬虫
从豆瓣电影搜索结果中爬取电影海报图片
"""

import os
import time
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.common.exceptions import WebDriverException
from PIL import Image
from urllib.parse import urljoin

class MoviePosterScraper:
    def __init__(self, download_dir="posters"):
        """
        初始化爬虫
        :param download_dir: 海报图片保存目录
        """
        self.download_dir = download_dir
        # 创建海报保存目录
        if not os.path.exists(self.download_dir):
            os.makedirs(self.download_dir)
        
        # 设置Chrome浏览器选项
        self.chrome_options = Options()
        self.chrome_options.add_argument('--headless')  # 无头模式
        self.chrome_options.add_argument('--no-sandbox')
        self.chrome_options.add_argument('--disable-dev-shm-usage')
        self.chrome_options.add_argument('--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36')
        
        # 初始化WebDriver
        self.driver = None
    
    def start_driver(self):
        """启动浏览器驱动"""
        try:
            # 使用webdriver-manager自动管理chromedriver
            service = Service(ChromeDriverManager().install())
            self.driver = webdriver.Chrome(service=service, options=self.chrome_options)
            return True
        except WebDriverException as e:
            if "offline" in str(e).lower():
                print("网络连接问题，尝试使用系统已安装的ChromeDriver")
                try:
                    self.driver = webdriver.Chrome(options=self.chrome_options)
                    return True
                except Exception as e2:
                    print(f"使用系统ChromeDriver也失败了: {e2}")
                    return False
            else:
                print(f"启动浏览器驱动失败: {e}")
                return False
        except Exception as e:
            print(f"启动浏览器驱动失败: {e}")
            return False
    
    def close_driver(self):
        """关闭浏览器驱动"""
        if self.driver:
            self.driver.quit()
    
    def search_movies(self, search_text):
        """
        搜索电影
        :param search_text: 搜索关键词
        :return: 电影海报链接列表
        """
        search_url = f"https://search.douban.com/movie/subject_search?search_text={search_text}&cat=1002"
        
        try:
            self.driver.get(search_url)
            time.sleep(5)  # 等待页面加载
            
            # 打印页面标题和部分源码用于调试
            print(f"页面标题: {self.driver.title}")
            
            # 尝试不同的选择器查找海报图片元素
            selectors = [
                "div.item-root a.cover-link img",
                "div.item-root img",
                "img[src*='img']",
                "img"
            ]
            
            poster_urls = []
            for selector in selectors:
                try:
                    poster_elements = self.driver.find_elements(By.CSS_SELECTOR, selector)
                    print(f"使用选择器 '{selector}' 找到 {len(poster_elements)} 个元素")
                    
                    for element in poster_elements:
                        src = element.get_attribute("src")
                        if src and ("img" in src or "doubanio" in src):
                            poster_urls.append(src)
                    
                    if poster_urls:
                        print(f"通过选择器 '{selector}' 找到 {len(poster_urls)} 张海报")
                        break
                        
                except Exception as e:
                    print(f"使用选择器 '{selector}' 时出错: {e}")
                    continue
            
            # 去重
            poster_urls = list(set(poster_urls))
            print(f"总共找到 {len(poster_urls)} 张不重复的海报")
            return poster_urls
            
        except Exception as e:
            print(f"搜索电影时出错: {e}")
            return []
    
    def download_image(self, url, filename):
        """
        下载图片
        :param url: 图片URL
        :param filename: 保存的文件名
        :return: 是否下载成功
        """
        try:
            headers = {
                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'
            }
            
            response = requests.get(url, headers=headers, timeout=10)
            response.raise_for_status()
            
            filepath = os.path.join(self.download_dir, filename)
            with open(filepath, 'wb') as f:
                f.write(response.content)
            
            print(f"已下载: {filename}")
            return True
            
        except Exception as e:
            print(f"下载图片失败 {url}: {e}")
            return False
    
    def scrape_posters(self, search_text, max_count=10):
        """
        爬取电影海报
        :param search_text: 搜索关键词
        :param max_count: 最大下载数量
        """
        print(f"开始搜索 '{search_text}' 的电影海报...")
        
        if not self.start_driver():
            print("无法启动浏览器驱动，程序退出")
            return
        
        try:
            poster_urls = self.search_movies(search_text)
            
            # 限制下载数量
            poster_urls = poster_urls[:max_count]
            
            # 下载海报
            for i, url in enumerate(poster_urls):
                filename = f"{search_text}_{i+1}.jpg"
                self.download_image(url, filename)
                time.sleep(1)  # 避免请求过于频繁
            
            print(f"完成！共下载 {len(poster_urls)} 张海报，保存在 {self.download_dir} 目录中")
            
        finally:
            self.close_driver()

def main():
    # 创建爬虫实例
    scraper = MoviePosterScraper(download_dir="posters")
    
    # 搜索并下载张柏芝的电影海报
    scraper.scrape_posters("张柏芝", max_count=5)

if __name__ == "__main__":
    main()